/*
  Test and validation of the SI4735 Arduino Library on ATtiny85.

  This sketch works with a fixed frequency and allows you to deal with SSB offset

  It is important to know the SSB support works on SI4735-D60 and SI4732-A10 devices. 
  This example shows the use of the external EEPROM. It will transfer the SSB patch content stored in an EEPROM 
  to SI4735-D60. To run this sketch you must have a external I2C EEPROM device configured with your ATtiny85 
  and the Si4735 devices via i2C bus. The EEPROM must have the patch content generated by the sketch  
  SI47XX_09_SAVE_SSB_PATCH_EEPROM. 
  See https://github.com/pu2clr/SI4735/tree/master/examples/TOOLS/SI47XX_09_SAVE_SSB_PATCH_EEPROM

  Other examples of using EEPROM and SSB patch: 
  https://github.com/pu2clr/SI4735/tree/master/examples/SI47XX_01_SERIAL_MONITOR/SI4735_06_SSB_EEPROM
  https://github.com/pu2clr/SI4735/tree/master/examples/TOOLS/SI47XX_10_USING_EEPROM_WITH_SSB

  Prototype documentation : https://pu2clr.github.io/SI4735/
  PU2CLR Si47XX API documentation: https://pu2clr.github.io/SI4735/extras/apidoc/html/

  By Ricardo Lima Caratti, Jan 2020.
*/

#include <SI4735.h>
#include <Tiny4kOLED.h>


#define RESET_PIN 3

#define EEPROM_ADDR 0x50

#define SSB_UP      1    // BFO offset up
#define SSB_DOWN    4    // BFO offset down
#define FM_FUNCTION 0
#define AM_FUNCTION 1
#define MAX_TIME 200

uint16_t currentFrequency;
uint16_t lastAmFrequency = 810;     // Starts AM on 810kHz;
uint16_t lastFmFrequency = 10390;   // Starts FM on 103,9MHz

int currentBFO = 0;
uint8_t currentBFOStep = 25;

long lastQuery = millis();

SI4735 si4735;

void setup()
{

  pinMode(SSB_DOWN, INPUT_PULLUP);
  pinMode(SSB_UP, INPUT_PULLUP);

  oled.begin();
  oled.clear();
  oled.on();
  oled.setFont(FONT8X16);
  oled.setCursor(0, 0);
  oled.print("Attiny85");
  delay(2000);
  oled.clear();

  oled.setCursor(0, 1);
  oled.print("SSB...");
  
  si4735.setup(RESET_PIN, AM_FUNCTION);
  delay(100);

  loadSSB();
  delay(1000);
  si4735.setSSB(520, 1710,  810, 10, 1);
  currentFrequency = si4735.getFrequency();
  si4735.setVolume(55);
  delay(100);
  showStatus();
}

/*
    Shows the currend frequency
*/
void showStatus() {
  oled.clear();
  oled.setCursor(5, 0);
  oled.print("BFO:");
  oled.setCursor(5, 2);
  oled.print(currentBFO);
}

void loadSSB()
{
  si4735_eeprom_patch_header eep;
  si4735.queryLibraryId(); // Is it really necessary here? I will check it.
  si4735.patchPowerUp();
  delay(50);
  eep = si4735.downloadPatchFromEeprom(EEPROM_ADDR);  

  oled.setCursor(0, 0);
  oled.print((char *) eep.refined.patch_id);
  oled.setCursor(0, 2);
  oled.print(eep.refined.patch_size);
   // Parameters
  // AUDIOBW - SSB Audio bandwidth; 0 = 1.2kHz (default); 1=2.2kHz; 2=3kHz; 3=4kHz; 4=500Hz; 5=1kHz;
  // SBCUTFLT SSB - side band cutoff filter for band passand low pass filter ( 0 or 1)
  // AVC_DIVIDER  - set 0 for SSB mode; set 3 for SYNC mode.
  // AVCEN - SSB Automatic Volume Control (AVC) enable; 0=disable; 1=enable (default).
  // SMUTESEL - SSB Soft-mute Based on RSSI or SNR (0 or 1).
  // DSP_AFCDIS - DSP AFC Disable or enable; 0=SYNC MODE, AFC enable; 1=SSB MODE, AFC disable.
  si4735.setSSBConfig(2, 1, 0, 1, 0, 1);
}

void loop()
{
  if (digitalRead(SSB_UP) == LOW ) {
     currentBFO += currentBFOStep;
     si4735.setSSBBfo(currentBFO);
     showStatus();
  } else if (digitalRead(SSB_DOWN) == LOW ) {
     currentBFO -= currentBFOStep;
     si4735.setSSBBfo(currentBFO);
    showStatus();
  }
  delay(50);
}
